package com.cars.satoken.config;

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import com.alibaba.fastjson2.JSON;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 注册拦截器
 *
 * @author: caoqianfan
 * @date: 2023/11/20 15:17:42
 */
@Configuration
public class SaTokenConfigure /*implements WebMvcConfigurer*/ {
//    /**
//     * 注册拦截器
//     * @param registry registry
//     */
//    @Override
//    public void addInterceptors(InterceptorRegistry registry) {
//        // 注册 Sa-Token 拦截器，定义详细认证规则
//        registry.addInterceptor(new SaInterceptor(handler -> {
//            // 指定一条 match 规则
//            SaRouter
//                    .match("/**")    // 拦截的 path 列表，可以写多个 */
//                    .notMatch("/login/doLogin")        // 排除掉的 path 列表，可以写多个
//                    .check(r -> StpUtil.checkLogin());        // 要执行的校验动作，可以写完整的 lambda 表达式
//
//            // 根据路由划分模块，不同模块不同鉴权
//            SaRouter
//                    .match("/user/add", r -> StpUtil.checkPermission("user-add"))
//                    .match("/user/delete", r -> StpUtil.checkPermission("user-delete"))
//                    .match("/user/update", r -> StpUtil.checkPermission("user-update"))
//                    .notMatch("/user/getById")
//                    .notMatch("/user/list");
//            SaRouter
//                    .match("/role/add", r -> StpUtil.checkPermission("role-add"))
//                    .match("/role/delete", r -> StpUtil.checkPermission("role-delete"))
//                    .match("/role/update", r -> StpUtil.checkPermission("role-update"))
//                    .notMatch("/role/getById")
//                    .notMatch("/role/list");
//            SaRouter
//                    .match("/permission/**", r -> StpUtil.checkPermission("permission"))
//                    .match("/permission/add", r -> StpUtil.checkPermission("permission-add"))
//                    .match("/permission/delete", r -> StpUtil.checkPermission("permission-delete"))
//                    .match("/permission/update", r -> StpUtil.checkPermission("permission-update"))
//                    .notMatch("/permission/getById")
//                    .notMatch("/permission/list");
//            //路由匹配角色，不同路由不同角色
//            SaRouter
//                    .match("/login/logout")
//                    .match("/login/kickout")
//                    .match("/disable/**")
//                    .check(r -> StpUtil.checkRole("admin"));
//        })).addPathPatterns("/**");
//    }

    /**
     * 注册 [Sa-Token全局过滤器]
     */
    @Bean
    public SaServletFilter getSaServletFilter() {
        return new SaServletFilter()

                // 指定 拦截路由 与 放行路由
                .addInclude("/**").addExclude("/favicon.ico")    /* 排除掉 /favicon.ico */

                // 认证函数: 每次请求执行
                .setAuth(obj -> {
                    System.out.println("---------- 进入Sa-Token全局认证 -----------");

                    // 登录认证 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
                    SaRouter.match("/**", "/login/doLogin", StpUtil::checkLogin);
                    // 根据路由划分模块，不同模块不同鉴权
                    SaRouter
                            .match("/user/add", r -> StpUtil.checkPermission("user-add"))
                            .match("/user/delete", r -> StpUtil.checkPermission("user-delete"))
                            .match("/user/update", r -> StpUtil.checkPermission("user-update"))
                            .notMatch("/user/getById", "/user/list");
                    SaRouter
                            .match("/role/add", r -> StpUtil.checkPermission("role-add"))
                            .match("/role/delete", r -> StpUtil.checkPermission("role-delete"))
                            .match("/role/update", r -> StpUtil.checkPermission("role-update"))
                            .notMatch("/role/getById", "/role/list");
                    SaRouter
                            .match("/permission/add", r -> StpUtil.checkPermission("permission-add"))
                            .match("/permission/delete", r -> StpUtil.checkPermission("permission-delete"))
                            .match("/permission/update", r -> StpUtil.checkPermission("permission-update"))
                            .notMatch("/permission/getById", "/permission/list");
                    //路由匹配角色，不同路由不同角色
                    SaRouter
                            .match("/login/logout", "/login/kickout", "/disable/**")
                            .check(r -> StpUtil.checkRole("admin"));

                    // 更多拦截处理方式，请参考“路由拦截式鉴权”章节 */
                })

                // 异常处理函数：每次认证函数发生异常时执行此函数
                .setError(e -> {
                    // 设置响应头
                    SaHolder.getResponse().setHeader("Content-Type", "application/json;charset=UTF-8");
                    // 使用封装的 JSON 工具类转换数据格式
                    return JSON.toJSONString(SaResult.error(e.getMessage()));
                })

                // 前置函数：在每次认证函数之前执行（BeforeAuth 不受 includeList 与 excludeList 的限制，所有请求都会进入）
                .setBeforeAuth(r -> {
                    // ---------- 设置一些安全响应头 ----------
                    SaHolder.getResponse()
                            // 服务器名称
                            .setServer("sa-server")
                            // 是否可以在iframe显示视图： DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
                            .setHeader("X-Frame-Options", "SAMEORIGIN")
                            // 是否启用浏览器默认XSS防护： 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时，停止渲染页面
                            .setHeader("X-XSS-Protection", "1; mode=block")
                            // 禁用浏览器内容嗅探
                            .setHeader("X-Content-Type-Options", "nosniff")
                    ;
                })
                ;
    }

}